﻿using System;
using Jayden.Dll.Cards.Poker.Enums;
using Jayden.Dll.Core.Persistence;
using Jayden.Dll.Core.Persistence.Attributes;
using System.Collections.Generic;

namespace Jayden.Dll.Cards.Poker
{
	[Table]
	public class TexasHoldemHandSummary : ObjectBase
	{
		private string m_ProviderName;
		private string m_TournamentId;
		private string m_HandReference;
		private string m_TableName;
		private DateTime m_HandDateTime;
		private uint m_ButtonNumber;
		private ulong m_TotalPot;
		private ulong m_Rake;
		private bool m_WentToShowdown;
		private ulong m_SmallBlind;
		private ulong m_BigBlind;
		private string m_Currency;
		private uint m_SeatCount;
		private uint m_PlayerCount;
		private PokerStreetType m_LastStreet;
		private CardList m_FlopCards;
		private Card m_TurnCard;
		private ulong m_Session;
		private Card m_RiverCard;

		public TexasHoldemHandSummary(UnitOfWork uow)
			: base(uow, 0)
		{

		}

		[Field(PrimaryKey = true, AutoIncrement = true)]
		public long TexasHoldemHandSummaryId { get { return (long)ObjectId[0]; } set { ObjectId[0] = value; } }
		[Field]
		public string ProviderName { get { return m_ProviderName; } set { m_ProviderName = value; } }
		[Field]
		public string TournamentId { get { return m_TournamentId; } set { m_TournamentId = value; } }
		[Field]
		public string HandReference { get { return m_HandReference; } set { m_HandReference = value; } }
		[Field]
		public string TableName { get { return m_TableName; } set { m_TableName = value; } }
		[Field]
		public DateTime HandDateTime { get { return m_HandDateTime; } set { m_HandDateTime = value; } }
		[Field]
		public uint ButtonNumber { get { return m_ButtonNumber; } set { m_ButtonNumber = value; } }
		[Field]
		public ulong TotalPot { get { return m_TotalPot; } set { m_TotalPot = value; } }
		[Field]
		public ulong Rake { get { return m_Rake; } set { m_Rake = value; } }
		[Field]
		public bool WentToShowdown { get { return m_WentToShowdown; } set { m_WentToShowdown = value; } }
		[Field]
		public ulong SmallBlind { get { return m_SmallBlind; } set { m_SmallBlind = value; } }
		[Field]
		public ulong BigBlind { get { return m_BigBlind; } set { m_BigBlind = value; } }
		[Field]
		public string Currency { get { return m_Currency; } set { m_Currency = value; } }
		[Field]
		public uint SeatCount { get { return m_SeatCount; } set { m_SeatCount = value; } }
		[Field]
		public uint PlayerCount { get { return m_PlayerCount; } set { m_PlayerCount = value; } }
		[Field]
		public PokerStreetType LastStreet { get { return m_LastStreet; } set { m_LastStreet = value; } }
		[Field]
		public ulong Session { get { return m_Session; } set { m_Session = value; } }
		[Field]
		public string Flop
		{
			get { return FlopCards == null ? null : FlopCards.ToString(); }
			set
			{
				if (string.IsNullOrWhiteSpace(value))
					FlopCards = null;
				else
					FlopCards = new CardList(Card.ParseArray(value));
			}
		}
		[Field]
		public string Turn
		{
			get { return TurnCard == null ? null : TurnCard.ToShortString(); }
			set
			{
				if (string.IsNullOrWhiteSpace(value))
					TurnCard = null;
				else
					TurnCard = Card.Parse(value);
			}
		}
		[Field]
		public string River
		{
			get { return RiverCard == null ? null : RiverCard.ToShortString(); }
			set
			{
				if (string.IsNullOrWhiteSpace(value))
					RiverCard = null;
				else
					RiverCard = Card.Parse(value);
			}
		}
		public string Community { get { return CommunityCards.ToString(); } }

		public bool HasFlop { get { return FlopCards != null && FlopCards.Count > 0; } }
		public bool HasTurn { get { return TurnCard != null; } }
		public bool HasRiver { get { return RiverCard != null; } }
		public CardList FlopCards { get { return m_FlopCards; } set { m_FlopCards = value; } }
		public Card TurnCard { get { return m_TurnCard; } set { m_TurnCard = value; } }
		public Card RiverCard { get { return m_RiverCard; } set { m_RiverCard = value; } }

		public bool HasShowdown { get { return LastStreet == PokerStreetType.Showdown; } }

		public CardList CommunityCards
		{
			get
			{
				CardList list = new CardList();
				if (HasFlop)
					list.AddRange(FlopCards);
				if (HasTurn)
					list.Add(TurnCard);
				if (HasRiver)
					list.Add(RiverCard);
				return list;
			}
		}

		private List<TexasHoldemPlayerHandSummary> m_Players;
		public List<TexasHoldemPlayerHandSummary> Players
		{
			get
			{
				if (m_Players == null)
				{
					TexasHoldemPlayerHandSummaryDataAccess dataAccess = UnitOfWork.DataAccessManager.GetDataAccess<TexasHoldemPlayerHandSummary>() as TexasHoldemPlayerHandSummaryDataAccess;
					m_Players = dataAccess.ReadByHandId(TexasHoldemHandSummaryId);
				}
				return m_Players;
			}
		}

		private List<TexasHoldemHandAction>[] m_Actions = new List<TexasHoldemHandAction>[Enum.GetValues(typeof(PokerStreetType)).Length];
		public List<TexasHoldemHandAction> this[PokerStreetType street]
		{
			get
			{
				if (LastStreet < street)
					return null;
				int index = (int)street;
				if (m_Actions[index] == null)
				{
					TexasHoldemHandActionDataAccess dataAccess = UnitOfWork.DataAccessManager.GetDataAccess<TexasHoldemHandAction>() as TexasHoldemHandActionDataAccess;
					m_Actions[index] = dataAccess.ReadByHandIdAndStreet(TexasHoldemHandSummaryId, street);
				}
				return m_Actions[index];
			}
		}
		public List<TexasHoldemHandAction> PreFlopActions { get { return this[PokerStreetType.PreFlop]; } }
		public List<TexasHoldemHandAction> FlopActions { get { return this[PokerStreetType.Flop]; } }
		public List<TexasHoldemHandAction> TurnActions { get { return this[PokerStreetType.Turn]; } }
		public List<TexasHoldemHandAction> RiverActions { get { return this[PokerStreetType.River]; } }
		public List<TexasHoldemHandAction> ShowdownActions { get { return this[PokerStreetType.Showdown]; } }
	}

}
